import { AbnormalType } from './type';

export enum ExceptionEvent {
    Tracking = 'tracking'
}
export type ExceptionHandler<T = Record<string, any>> = (
    data: {
        monitorType: AbnormalType | 'tracking';
        monitorSubType?: string;
        monitorName: string;
        trackingKey: string;
        [key: string]: any;
    },
    globals: T
) => void;
class Monitor {
    handlers: Map<ExceptionEvent, ExceptionHandler>;
    globals: Map<string, any>;

    constructor() {
        this.handlers = new Map();
        this.globals = new Map<string, any>();
    }
    triggerHook(eventName: ExceptionEvent, params: any) {
        if (this.handlers.has(eventName)) {
            const callback = this.handlers.get(eventName);
            const globals = this.getAllGlobals();
            typeof callback === 'function' && callback(params, globals);
        }
    }

    on(eventName: ExceptionEvent, callback: ExceptionHandler) {
        if (!this.handlers.has(eventName)) {
            this.handlers.set(eventName, callback);
        }
    }
    // 取消事件注册
    off(eventName: ExceptionEvent, callback?: ExceptionHandler): void {
        if (!this.handlers.has(eventName)) {
            return;
        }
        if (callback) {
            // 移除特定处理器
            this.handlers.delete(eventName);
        }
    }

    setGlobal(key: string, value: any): void {
        if (typeof key !== 'string' || key.trim() === '') {
            console.warn('全局变量的键名必须是非空字符串');
            return;
        }
        this.globals.set(key, value);
    }

    setGlobals(data: Record<string, any>): void {
        if (typeof data !== 'object' || data === null) {
            console.warn('批量设置全局变量必须提供对象类型数据');
            return;
        }

        Object.entries(data).forEach(([key, value]) => {
            this.setGlobal(key, value);
        });
    }

    // 新增：获取全局变量
    getGlobal(key: string): any {
        if (typeof key !== 'string' || key.trim() === '') {
            console.warn('获取全局变量必须提供有效的键名');
            return undefined;
        }
        return this.globals.get(key);
    }

    // 新增：检查全局变量是否存在
    hasGlobal(key: string): boolean {
        if (typeof key !== 'string' || key.trim() === '') {
            return false;
        }
        return this.globals.has(key);
    }

    // 新增：删除全局变量
    removeGlobal(key: string): void {
        if (typeof key !== 'string' || key.trim() === '') {
            console.warn('删除全局变量必须提供有效的键名');
            return;
        }
        this.globals.delete(key);
    }

    // 新增：清空所有全局变量
    clearGlobals(): void {
        this.globals.clear();
    }
    getAllGlobals(): Record<string, any> {
        const result: Record<string, any> = {};
        this.globals.forEach((value, key) => {
            result[key] = value;
        });
        return result;
    }

    destroy(): void {
        this.handlers.clear();
        this.globals.clear();
    }
}

const createMonitor = (function () {
    let instance: Monitor | null = null;
    return function () {
        if (!instance) {
            instance = new Monitor();
        }
        return instance;
    };
})();

export default createMonitor;
